<template>
  <devicePanel
    :panel-data="switchData.panelData"
    :common-type="deviceInfo.commonType"
    :sn="deviceInfo.serialNumber"
    :groupId="deviceInfo.groupId"
    :productClass="deviceInfo.productClass"
    :select-port="portselect"
    @childSelectPort="selectPort"
    ref="switchPanel"
  >
    <template slot="legend" v-if="showLegend">
      <portIcon></portIcon>
    </template>
    <template slot="ports" slot-scope="{ port, index, sn }">
      <div
        style="position: relative; padding: 0px 4px"
        ondragstart="return false;"
        @mouseenter.self="activePortData(port)"
      >
        <a-tooltip>
          <template slot="title">
            <div class="portStatus">
              <p>
                <span>{{ $t('common.port') }}</span
                ><span>{{ currentSelectData.order }}</span>
              </p>
              <p>
                <span>{{ $t('deviceDetail.portStatus') }}</span
                ><span>{{ currentSelectData.status }}</span>
              </p>
              <p>
                <span>{{ $t('deviceDetail.speed') }}</span
                ><span>{{ currentSelectData.speed }}</span>
              </p>
              <p>
                <span>{{ $t('common.traffic') }}</span>
                <span>
                  <a-icon type="arrow-down" style="color: #44f633" />
                  {{ input }}KB
                  <a-icon type="arrow-up" style="color: #ff9344" />
                  {{ output }}KB
                </span>
              </p>
              <p>
                <span>{{ $t('common.speed') }}</span>
                <span>
                  <a-icon type="arrow-down" style="color: #44f633" />
                  {{ downRate }}Kbps

                  <a-icon type="arrow-up" style="color: #ff9344" />
                  {{ upRate }}Kbps
                </span>
              </p>
              <p>
                <span>{{ $t('deviceDetail.packets') }}</span>
                <span>
                  <a-icon type="arrow-down" style="color: #44f633" />
                  {{ inputPacket }}
                  <a-icon type="arrow-up" style="color: #ff9344" />
                  {{ outputPacket }}
                </span>
              </p>
              <p>
                <span>{{ $t('deviceDetail.mediaType') }}</span
                ><span>{{
                  currentSelectData.mediumType == 'Fiber'
                    ? $t('deviceDetail.sfp')
                    : currentSelectData.mediumType == 'fiberBranch'
                    ? $t('deviceDetail.fiberBranch')
                    : $t('deviceDetail.copper')
                }}</span>
              </p>
              <p v-if="currentSelectData.fiberPortInfo">
                <span>{{ $t('switchPanel.opticalDistribution') }}</span>
                <span><span>--</span></span>
              </p>
              <p v-if="currentSelectData.fiberPortInfo">
                <span>{{ $t('switchPanel.distance') }}</span>
                <span
                  ><span
                    >{{ currentSelectData.fiberPortInfo.distance }}m
                  </span></span
                >
              </p>
              <p v-if="currentSelectData.fiberPortInfo">
                <span>{{ $t('switchPanel.temperature') }}</span>
                <span
                  ><span
                    :class="[
                      checkRangeOut(
                        'temperature',
                        currentSelectData.fiberStatus
                      ).result
                        ? 'out'
                        : 'in',
                    ]"
                    >{{ currentSelectData.fiberPortInfo.temperature }}℃
                    <a-icon
                      :type="`arrow-${
                        checkRangeOut(
                          'temperature',
                          currentSelectData.fiberStatus
                        ).arrow
                      }`"
                      v-if="
                        checkRangeOut(
                          'temperature',
                          currentSelectData.fiberStatus
                        ).result
                      " /></span
                ></span>
              </p>
              <p v-if="currentSelectData.fiberPortInfo">
                <span>{{ $t('switchPanel.voltage') }}</span>

                <span
                  ><span
                    :class="[
                      checkRangeOut('voltage', currentSelectData.fiberStatus)
                        .result
                        ? 'out'
                        : 'in',
                    ]"
                    >{{ currentSelectData.fiberPortInfo.voltage }}V
                    <a-icon
                      :type="`arrow-${
                        checkRangeOut('voltage', currentSelectData.fiberStatus)
                          .arrow
                      }`"
                      v-if="
                        checkRangeOut('voltage', currentSelectData.fiberStatus)
                          .result
                      " /></span
                ></span>
              </p>
              <p v-if="currentSelectData.fiberPortInfo">
                <span>{{ $t('switchPanel.current') }}</span>
                <span
                  ><span
                    :class="[
                      checkRangeOut('bias', currentSelectData.fiberStatus)
                        .result
                        ? 'out'
                        : 'in',
                    ]"
                    >{{ currentSelectData.fiberPortInfo.bias }}mA
                    <a-icon
                      :type="`arrow-${
                        checkRangeOut('bias', currentSelectData.fiberStatus)
                          .arrow
                      }`"
                      v-if="
                        checkRangeOut('bias', currentSelectData.fiberStatus)
                          .result
                      " /></span
                ></span>
              </p>
              <p v-if="currentSelectData.fiberPortInfo">
                <span>{{
                  currentSelectData.uplink
                    ? $t('switchPanel.rxPower')
                    : $t('switchPanel.txPower')
                }}</span>
                <span
                  ><span
                    :class="[
                      checkRangeOut('power', currentSelectData.fiberStatus)
                        .result
                        ? 'out'
                        : 'in',
                    ]"
                    >{{
                      currentSelectData.uplink
                        ? currentSelectData.fiberPortInfo.rxPower
                        : currentSelectData.fiberPortInfo.txPower
                    }}dBm
                    <a-icon
                      :type="`arrow-${
                        checkRangeOut('power', currentSelectData.fiberStatus)
                          .arrow
                      }`"
                      v-if="
                        checkRangeOut('power', currentSelectData.fiberStatus)
                          .result
                      " /></span
                ></span>
              </p>

              <p>
                <span>{{ $t('deviceDetail.interfaceType') }}</span
                ><span>{{ currentSelectData.type }}</span>
              </p>
              <p class="portStatus-vlan">
                <span>VLAN</span>
                <span style="margin-left: 10px">
                  Native Id: {{ SwitchPortVlanL3Info.vlan }}<br />
                  Allowed Vlan: {{ SwitchPortVlanL3Info.vlanList }}<br />
                  {{ $t('deviceDetail.realVlan') }}:
                  {{ SwitchPortVlanL3Info.actualAllowVlan }}
                </span>
              </p>
            </div>
          </template>
          <a-badge :dot="checkError(port)">
            <icon-font
              :type="getDevicePanelPortIcon(port.mediumType)"
              :rotate="index % 2 == 0 ? 0 : 180"
              :style="{ fontSize: '18px' }"
              :class="[
                'port-icon',
                checkSpeed(port, sn),
                checkDisable(port, sn),
              ]"
            />
          </a-badge>
        </a-tooltip>
        <div
          style="pointer-events: none"
          v-for="(icon, index) in getPortIcon(port)"
          :key="'portIcon' + index"
        >
          <icon-font
            v-if="iconTypeMap.over[icon]"
            :type="'ic-' + iconTypeMap.over[icon]"
            :style="{
              fontSize: '18px',
              position: 'absolute',
              top: '-3px',
            }"
            class="over-icon"
          ></icon-font>
          <icon-font
            v-if="iconTypeMap.status[icon]"
            :type="'ic-' + iconTypeMap.status[icon]"
            class="status-icon"
          ></icon-font>
        </div>
      </div>
    </template>
  </devicePanel>
</template>
<script>
import { requestHttp, maccApi } from '@utils/index';
import {
  getDevicePanelLayout, // 获取设备面板布局
  iconTypeMap, //图标映射关系
  greenSpeed,
  getSwitchOrder,
  getDevicePanelPortIcon,
  checkMultiplexing,
} from '@utils/deviceTools';
import _ from 'lodash';
import { devicePanel } from '@components';
import portIcon from './portIcon.vue';
import { mapState } from 'vuex';
export default {
  name: 'SwitchCommnPanel',
  components: {
    devicePanel,
    portIcon,
  },
  props: {
    deviceInfo: {
      type: Object,
      default: () => {},
    },
    portselect: {
      type: Array,
      default: () => [],
    },
    showLegend: {
      type: Boolean,
      default: true,
    },
  },
  watch: {
    deviceInfo: {
      handler() {
        this.initPanel();
      },
      deep: true,
    },
  },
  mounted() {
    this.initPanel();
  },
  computed: {
    input() {
      let uplink = this.currentSelectData.uplink;

      if (this.interfaceFlow && uplink) {
        return (this.interfaceFlow.input / 1024).toFixed(2);
      } else if (this.interfaceFlow && !uplink) {
        return (this.interfaceFlow.output / 1024).toFixed(2);
      } else {
        return '-';
      }
    },
    output() {
      let uplink = this.currentSelectData.uplink;

      if (this.interfaceFlow && uplink) {
        return (this.interfaceFlow.output / 1024).toFixed(2);
      } else if (this.interfaceFlow && !uplink) {
        return (this.interfaceFlow.input / 1024).toFixed(2);
      } else {
        return '-';
      }
    },

    downRate() {
      let uplink = this.currentSelectData.uplink;

      if (this.interfaceFlow && uplink) {
        return (this.interfaceFlow.downRate * 8).toFixed(2);
      } else if (this.interfaceFlow && !uplink) {
        return (this.interfaceFlow.upRate * 8).toFixed(2);
      } else {
        return '-';
      }
    },

    upRate() {
      let uplink = this.currentSelectData.uplink;

      if (this.interfaceFlow && uplink) {
        return (this.interfaceFlow.upRate * 8).toFixed(2);
      } else if (this.interfaceFlow && !uplink) {
        return (this.interfaceFlow.downRate * 8).toFixed(2);
      } else {
        return '-';
      }
    },
    inputPacket() {
      let uplink = this.currentSelectData.uplink;

      if (this.interfaceFlow && uplink) {
        return this.interfaceFlow.inputPacket;
      } else if (this.interfaceFlow && !uplink) {
        return this.interfaceFlow.outputPacket;
      } else {
        return '-';
      }
    },
    outputPacket() {
      let uplink = this.currentSelectData.uplink;

      if (this.interfaceFlow && uplink) {
        return this.interfaceFlow.outputPacket;
      } else if (this.interfaceFlow && !uplink) {
        return this.interfaceFlow.inputPacket;
      } else {
        return '-';
      }
    },
    ...mapState('DeviceDetail', {
      portsMap: (state) => {
        const currentDevicePortsData = state.switch.currentDevicePortsData;
        const renderData = {};
        for (let i = 0; i < currentDevicePortsData.length; i++) {
          const item = currentDevicePortsData[i];
          let orderId = '';
          if (
            item.devOrder != undefined &&
            item.slotOrder != undefined &&
            item.order != undefined
          ) {
            //交换机数据格式
            orderId = `${item.devOrder}_${item.slotOrder}_${getSwitchOrder(
              item
            )}`;
          } else {
            //网关端口列表
            orderId = `${item.port}`;
          }

          const itemData = { mediumType: item.mediumType };
          itemData.portData = item;
          renderData[orderId] = itemData;
        }
        return renderData;
      },
      agMap: (state) => {
        const currentDevicePortsData = state.switch.currentDevicePortsData;
        const agobj = {};
        if (
          Object.prototype.toString.call(currentDevicePortsData) ==
            '[object Array]' &&
          currentDevicePortsData.length > 0
        ) {
          for (let i = 0; i < currentDevicePortsData.length; i++) {
            const item = currentDevicePortsData[i];
            let orderId = '';
            if (
              item.devOrder != undefined &&
              item.slotOrder != undefined &&
              item.order != undefined
            ) {
              //交换机数据格式
              orderId = `${item.devOrder}_${item.slotOrder}_${getSwitchOrder(
                item
              )}`;
            } else {
              //网关端口列表
              orderId = `${item.port}`;
            }
            if (item.portGroupId > 0) {
              if (agobj[item.portGroupId]) {
                agobj[item.portGroupId].push(orderId);
              } else {
                agobj[item.portGroupId] = [];
                agobj[item.portGroupId].push(orderId);
              }
            }
          }
        }
        return agobj;
      },
    }),
  },
  data() {
    return {
      // slotInfo: [],
      //portselect: [],
      selectPortData: [],
      currentSelect: '',
      currentSelectData: '',
      portPanel: [],
      //portList: [],
      timer: '',

      switchData: {
        panelData: [],
        portDataMap: {},
      },

      interfaceFlow: {},

      SwitchPortVlanL3Info: {},

      iconTypeMap,
    };
  },

  methods: {
    getDevicePanelPortIcon,
    /**
     * @description: 设置端口颜色
     * @param {*} port
     * @return {*}
     */
    checkSpeed(port) {
      let speedClass = '';
      const portSwInfo = this.portsMap[port.portorder];
      speedClass = this.formatterSwSpeed(portSwInfo);
      // 区分交换机和网关数据
      return speedClass;
    },

    /**
     * @description: 网速区分颜色
     * @param {*}
     * @return {*}
     */
    formatterSwSpeed(portInfo) {
      let speedClass = '';
      if (portInfo && portInfo.portData.enable == 'true') {
        const speed = portInfo.portData.speed;
        const status = portInfo.portData.status;
        if (status == 'Up') {
          if (greenSpeed.indexOf(speed) > -1) {
            speedClass = 'green';
          } else {
            speedClass = 'yellow';
          }
        } else if (status == 'Down') {
          speedClass = 'black';
        } else if (status == 'Dormant') {
          speedClass = 'gray';
        } else if (status == 'Unknown') {
          speedClass = 'red';
        }
      }

      return speedClass;
    },
    /**
     * @description:请求面板数据
     * @param {*}
     * @return {*}
     */
    async getSlotsLayout(sn, pc) {
      // debugger;
      const slotsLayout = await getDevicePanelLayout(sn, pc, this.$store);
      console.log('..........面板数据', sn, pc, slotsLayout);
      //面板未开启
      slotsLayout.forEach((item) => {
        if (item.ports == null) {
          item.ports = [];
        }
      });
      // debugger;
      this.portPanel = slotsLayout;
    },

    /**
     * @description: 初始化面板
     * @param {*}
     * @return {*}
     */
    async initPanel() {
      // debugger;
      // this.portselect = [];
      this.selectPortData = [];

      await this.getSlotsLayout(
        this.deviceInfo.serialNumber,
        this.deviceInfo.productClass
      );

      this.switchData.panelData = this.portPanel;
    },
    /**
     * @description: 处理选中接口
     * @param {*} data
     * @return {*}
     */
    selectPort(data) {
      this.$emit('panelSelectPorts', data);
    },

    //校验是否上联口,上联口不允许进行标记或进行禁止重启操作
    checkUplink(port) {
      const portData =
        (this.portsMap[port.portorder] &&
          this.portsMap[port.portorder].portData) ||
        {};
      return portData.uplink;
    },
    //判断端口是否可用，并进行渲染
    checkDisable(port, sn) {
      let disableClass = '';

      let portData;
      portData = this.portsMap[port.portorder];

      //判断
      if (portData) {
        //判断光电复用口

        if (!checkMultiplexing(portData.mediumType, port.mediumType)) {
          disableClass = 'disbaled';
        }
        //判断端口是否关闭
        if (portData.portData.enable == 'false') {
          disableClass = 'disbaled';
        }
      } else {
        disableClass = 'disbaled';
      }
      // debugger;
      return disableClass;
    },

    /**
     * @description: 获取鼠标经过的接口数据
     * @param {*}
     * @return {*}
     */
    activePortData: _.debounce(async function (port) {
      this.currentSelectData = {
        ...(this.portsMap?.[port.portorder]?.portData ?? {}),
      };
      const flowRes = await this.getSwitchPortsFlowInfo([
        this.currentSelectData.alias,
      ]);
      if (flowRes && flowRes.code == 0) {
        this.interfaceFlow = flowRes.interfaceFlow && flowRes.interfaceFlow[0];
      }
      this.getSwitchPortVlanL3Info();
      console.log(this.currentSelectData, 'this.currentSelectData');
    }, 500),
    /**
     * @description: 判断设备端口图标
     * @param {*}
     * @return {*}
     */
    checkPortIcon(port, portLayoutData) {
      //portData.portData;
      //上联口
      const portIcon = [];
      if (port.uplink) {
        //return 'union';
        portIcon.push('union');
      }
      //poe供电
      if (port.poeStatus == 'On') {
        //return 'poe';
        if (port.hpoe) {
          portIcon.push('hpoe');
        } else {
          portIcon.push('poe');
        }
      }
      //供电异常
      if (port.poeStatus == 'Erroneous') {
        //return 'poeEabnormal';
        portIcon.push('poeEabnormal');
      }
      //阻塞
      if (port.isBlock == 'TRUE' && port.status != 'Down') {
        //return 'block';
        portIcon.push('block');
      }

      if (port.loopState == 'true' && port.status != 'Down') {
        portIcon.push('loop');
      }

      if (
        port.mediumType == 'fiberBranch' &&
        portLayoutData.mediumType == 'Fiber'
      ) {
        //debugger;
        portIcon.push('fs');
      }

      // if (this.portIcon[port.alias]) {
      //   portIcon.push(this.portIcon[port.alias]);
      // }
      // console.log('================ports', port, portIcon);
      return portIcon;
    },
    getPortIcon(port) {
      const currentPortData = this.portsMap[port.portorder];
      //判断是否当前生效口
      const mediumType = currentPortData && currentPortData.mediumType;

      if (checkMultiplexing(mediumType, port.mediumType)) {
        //端口数据无mediumType判断
        return (
          (currentPortData &&
            this.checkPortIcon(currentPortData.portData, port)) ??
          []
        );
      } else {
        return [];
      }
    },
    async getSwitchPortsFlowInfo(alias) {
      var params = {
        sn: this.deviceInfo.serialNumber,
        buildingId: this.deviceInfo.groupId,
        interfaceShorts: alias,
      };
      var data = {
        api: maccApi.SWITCH_PORTSFLOWINFO_POST_API,
        method: 'POST',
        params,
        module: 'logbiz',
      };
      let res = await requestHttp(data);
      return res;
      // if (res && res.code == 0) {
      //   //TODO
      //   this.interfaceFlow = res.interfaceFlow[0];
      //   //console.log(this.interfaceFlow, 'this.interfaceFlow ');
      // }
    },
    async getSwitchPortVlanL3Info() {
      // var params = {
      //   sn: this.deviceInfo.serialNumber,
      //   alias: this.currentSelectData.alias
      // }
      var api = maccApi.SWITCH_NETWORKSWITCHPORTVLAN_GET_API.replace(
        '{sn}',
        this.deviceInfo.serialNumber
      ).replace('{alias}', encodeURIComponent(this.currentSelectData.alias));

      var data = {
        api,
        method: 'GET',
      };
      let res = await requestHttp(data);
      if (res && res.code == 0) {
        //TODO
        this.SwitchPortVlanL3Info = res.portInfo;
      }
    },
    //根据orderList获取端口数据
    getPortsDataForOrder(orderList) {
      return orderList.map((item) => {
        return this.portsMap[item].portData;
      });
    },
    //判断光口状态
    checkRangeOut(type, fiberStatus) {
      let result = false,
        arrow = '';
      const status = [];
      for (let i = 0; i < 6; i++) {
        status.push(
          parseInt(Math.pow(10, i), 2) &
            (fiberStatus == parseInt(Math.pow(10, i), 2))
        );
      }
      switch (type) {
        case 'power': {
          //判断光强弱
          if (status[0]) {
            result = true;
            arrow = 'down';
          }
          //判断光强高
          if (status[1]) {
            result = true;
            arrow = 'up';
          }
          break;
        }
        case 'temperature': {
          //判断温度高
          if (status[2]) {
            result = true;
            arrow = 'up';
          }
          break;
        }
        case 'bias': {
          //判断电流高
          if (status[3]) {
            result = true;
            arrow = 'up';
          }
          //判断电流低
          if (status[4]) {
            result = true;
            arrow = 'down';
          }
          break;
        }
        case 'voltage': {
          //判断电压高
          if (status[5]) {
            result = true;
            arrow = 'up';
          }
          //判断电压低
          if (status[6]) {
            result = true;
            arrow = 'down';
          }
          break;
        }
      }
      return { result, arrow };
    },
    getFiberStatus(status) {
      const fiberStatus = {
        5: '电压异常',
        4: '电流异常',
        3: '光模块温度过高',
        2: '光强高',
        1: '光强弱',
        0: '正常',
      };
      return fiberStatus[status];
    },
    checkError(port) {
      let res = false;
      const currentPortData = this.portsMap?.[port.portorder]?.portData ?? {};
      if (currentPortData && currentPortData.fiberStatus > 0) {
        return true;
      }
      return res;
    },
  },
};
</script>
<style scoped lang="less">
.view-title {
  border-bottom: 1px solid #bfbfbf;
  width: 100%;
  color: #262626;
  padding: 10px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
  margin-bottom: 8px;
}
.port-icon {
  color: @portBlack;
  &.green {
    color: @portGreen;
  }
  &.yellow {
    color: @portYellow;
  }
  &.red {
    color: @portRed;
  }
  &.disbaled {
    color: @portDisabled;
  }
}

.iconBox {
  text-align: center;
}

.over-icon {
  color: #fff;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 13px;
}
.status-icon {
  position: absolute;
  width: 16px;
  height: 16px;
  border-radius: 16px;
  border: 1px solid #595959;
  color: #595959;
  text-align: center;
  line-height: 16px;
  background-color: #fff;
  z-index: 2;
  bottom: 0px;
  right: 0px;
  transform: scale(0.75);
}

.portStatus {
  min-width: 200px;
  font-size: 12px;
}
.portStatus p {
  display: flex;
  justify-content: space-between;
}
.portStatus-vlan {
  display: block;
}

.icon-content {
  position: relative;
  .icon-port {
    font-size: 18px;
    color: #d9d9d9;
  }
  .icon-status,
  .icon-over {
    position: absolute;
    color: #595959;
  }
  .icon-over {
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 14px;
  }
  .icon-status {
    width: 16px;
    height: 16px;
    border-radius: 16px;
    border: 1px solid #595959;
    background-color: #fff;
    line-height: 16px;
    text-align: center;
    bottom: 0px;
    right: 33px;
    transform: scale(0.75);
  }
}
.in {
  color: @success-color;
}
.out {
  color: @warning-color;
}
</style>
